Skip to content

rule: Changes IPProto type to u8 - #1190

Open
tsheinen wants to merge 1 commit into
vishvananda:mainfrom
tsheinen:rule-protocol-type
Open

rule: Changes IPProto type to u8#1190
tsheinen wants to merge 1 commit into
vishvananda:mainfrom
tsheinen:rule-protocol-type

Conversation

@tsheinen

@tsheinen tsheinen commented Jun 3, 2026

Copy link
Copy Markdown

netlink defines1 the type of FRA_IP_PROTO to be a u8 but the definition in rule.go treats this field as a u32. This causes messages to appear in kernel logs with "attribute type 22 has an invalid length." This is exercised in TestRuleAddDel, although it does not cause the test to fail because netlink parses it permissively.

Summary by CodeRabbit

  • Refactor
    • Improved handling of protocol values in network rule creation and listing for better compatibility with the kernel, resulting in more reliable rule application and retrieval.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 55dfd778-c48c-4415-8d52-d2bf047bfe63

📥 Commits

Reviewing files that changed from the base of the PR and between 1d9df8c and 577f043.

📒 Files selected for processing (2)
  • rule.go
  • rule_linux.go
✅ Files skipped from review due to trivial changes (1)
  • rule.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • rule_linux.go

📝 Walkthrough

Walkthrough

Adds an inline comment to Rule.IPProto and changes Linux netlink handling of FRA_IP_PROTO to encode a single byte ([]byte{byte(rule.IPProto)}) and to deserialize by reading the attribute's first byte.

Changes

FRA_IP_PROTO single-byte encoding

Layer / File(s) Summary
Netlink FRA_IP_PROTO handling
rule.go, rule_linux.go
A comment was added to Rule.IPProto noting the kernel represents it as uint8. Linux netlink encoding now sends FRA_IP_PROTO as a 1-byte payload []byte{byte(rule.IPProto)}; listing/deserialization reads attrs[j].Value[0] for IPProto.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I nibble bytes both short and sweet,
One tiny proto, tidy and neat,
From comment scrawl to kernel line,
A single byte now does the sign,
Hooray — small hops make code complete! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: updating IPProto handling from 32-bit to 8-bit to align with kernel netlink specifications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rule.go`:
- Line 28: The public field Rule.IPProto was narrowed from int to uint8,
breaking callers that pass/read int values (and tests using unix.IPPROTO_UDP);
revert Rule.IPProto back to type int to preserve the API surface, and adjust
encoding/decoding in rule_linux.go (the FRA_IP_PROTO handling) to cast between
int and uint8 where necessary so internal netlink bytes remain a single byte
while the public type stays int; update any tests to use the int-typed field if
needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 68ffd1aa-9ed3-4e29-9683-2c4c4310b3c1

📥 Commits

Reviewing files that changed from the base of the PR and between 99e9797 and 1d9df8c.

📒 Files selected for processing (2)
  • rule.go
  • rule_linux.go

Comment thread rule.go Outdated
@vishvananda

Copy link
Copy Markdown
Owner

coderabbit's suggestion is correct here, we don't want to change the public interface here as it may break callers.

@tsheinen

tsheinen commented Jun 3, 2026

Copy link
Copy Markdown
Author

coderabbit's suggestion is correct here, we don't want to change the public interface here as it may break callers.

I considered that, but was of the opinion that it was an easily fixed breaking change and that it would be worse to silently change the semantics outside of the type system. If we need to narrow u32 to u8 before sending it to the kernel, we'll either have to return an error or silently discard upper bits. I suppose that given the kernel is already silently discarding larger values, doing it in userspace as well can't really change semantics.

Do you have a preference on how to handle the narrowing?

@aboch

aboch commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

I agree it's unfortunate the Rule struct has IPProto as an int, but also I the issue is minor. The changes required to not break the existing API, which I am afraid are creating a new Rule2 struct, may not be worth in this case.

netlink defines[1] the type of FRA_IP_PROTO to be a u8 but the definition in
rule.go treats this field as a u32. This causes messages to appear in
kernel logs with "attribute type 22 has an invalid length." This is
exercised in TestRuleAddDel, although it does not cause the test to
fail because netlink parses it permissively.

The type of `IPProto` in `type Rule` is left as int to avoid a breaking
API change. Instead, it is truncated in userspace before sending to the
kernel. Truncation is how the kernel handles larger values, so we don't
expect this to change semantics.

[1]: https://elixir.bootlin.com/linux/v6.19.14/source/net/core/fib_rules.c#L862

Co-authored-by: conjones <connerj@cloudflare.com>
@tsheinen
tsheinen force-pushed the rule-protocol-type branch from 1d9df8c to 577f043 Compare June 4, 2026 14:37
@tsheinen

tsheinen commented Jun 4, 2026

Copy link
Copy Markdown
Author

I amended the commit to not change the type of IPProto and instead truncate it in userspace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants